package com.xiaoxie.common.redis;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class RedisSerializer implements CommandLineRunner {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    static {
        try{
            // 设置对象可见性为字段级别
            OBJECT_MAPPER.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
            // 禁用默认的多态类型处理，改为显式指定允许的类
            OBJECT_MAPPER.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,
                ObjectMapper.DefaultTyping.NON_FINAL);
        } catch (Exception e) {
            log.error("初始化ObjectMapper失败:{}", e.getMessage(), e);
            throw new RuntimeException("初始化ObjectMapper失败",e);
        }

        if (OBJECT_MAPPER == null) {
            throw new IllegalStateException("OBJECT_MAPPER 未正确初始化");
        }
    }

    @Override
    public void run(String... args) throws Exception {
        log.info("Redis序列化开始...");
        // key序列化
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        // 创建Jackson序列化器
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(OBJECT_MAPPER, Object.class);
        // value序列化
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        // HashKey序列化
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        // HashValue序列化
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        log.info("Redis序列化完成...");


    }
}
